﻿//-----------------------------------------------------------------------
// <copyright file="RequestManager.cs" company="Paul V. Borza">
// http://fastget.codeplex.com/license
// </copyright>
//-----------------------------------------------------------------------

namespace FastGet
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    internal static class RequestManager
    {
        public static void Setup(int connectionCount)
        {
            // increases the default connection limit (two is default)
            ServicePointManager.DefaultConnectionLimit = connectionCount;
        }

        public static void Start(Queue<HttpWebRequest> queue, HashSet<string> cache, string outputPath)
        {
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            var tasks = new List<Task>(queue.Count);

            while (queue.Count > 0)
            {
                var request = queue.Dequeue();

                var fileName = string.Format(CultureInfo.InvariantCulture, "{0}.txt", request.RequestUri.ToString().ToSafeString());

                var path = Path.Combine(outputPath, fileName);

                if (cache.Contains(fileName) || File.Exists(path))
                {
                    // Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Skipping {0} as it already exists", path));
                    continue;
                }

                try
                {
                    var whenRequestCompleted = request.GetResponseAsync();
                    CounterManager.HttpRequests.Increment();

                    tasks.Add(whenRequestCompleted);

                    whenRequestCompleted.ContinueWith((t, p) => { Save((HttpWebResponse)t.Result, (string)p); }, path, TaskContinuationOptions.OnlyOnRanToCompletion);
                }
                catch (WebException)
                {
                    queue.Enqueue(request);
                }
            }

            try
            {
                Task.WaitAll(tasks.ToArray());
            }
            catch (AggregateException ex)
            {
                return;
            }
        }

        private static void Save(HttpWebResponse response, string path)
        {
            try
            {
                CounterManager.HttpResponses.Increment();

                var body = string.Empty;
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    body = reader.ReadToEnd();
                }

                File.WriteAllText(path, body);
            }
            catch (WebException)
            {
                // ignores the exceptions
                return;
            }
        }
    }
}
